namespace UnityEngine.Rendering.Universal.Internal
{
    public class BlitColorPass : ScriptableRenderPass
    {
        public enum BlitColorTransform
        {
            None,
            GammaToLine,
            LineToGamma
        }

        int m_Width;
        int m_Height;
        readonly Material m_BlitMaterial;
        BlitColorTransform m_BlitColorTransform;
        
        public BlitColorPass(RenderPassEvent evt, Material blitMaterial)
        {
            m_BlitMaterial = blitMaterial;
            renderPassEvent = evt;
            useNativeRenderPass = false;
        }


        public void Setup(int width, int height, BlitColorTransform blitColorTransform)
        {
            m_Width = width;
            m_Height = height;
            m_BlitColorTransform = blitColorTransform;
        }
        
        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            if (m_BlitMaterial == null)
            {
                Debug.LogErrorFormat("BlitColorPass 缺少后处理材质球!!!");
                return;
            }

            CommandBuffer cmd = CommandBufferPool.Get("BlitColor");
            
            var renderer = renderingData.cameraData.renderer as UniversalRenderer;
            var colorBuffer = renderer.m_ColorBufferSystem;
            var needChangeSize = RenderTargetBufferSystem.m_Desc.width != m_Width || RenderTargetBufferSystem.m_Desc.height != m_Height;

            if (needChangeSize) colorBuffer.ReSizeFrontBuffer(cmd, m_Width, m_Height);
            
            var useDrawProceduleBlit = renderingData.cameraData.xr.enabled;

            switch (m_BlitColorTransform)
            {
                case BlitColorTransform.GammaToLine:
                    CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.LinearToSRGBConversion, false);
                    CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SRGBToLinearConversion, true);
                    break;
                case BlitColorTransform.LineToGamma:
                    CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.LinearToSRGBConversion, true);
                    CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SRGBToLinearConversion, false);
                    break;
            }

            var source = renderingData.cameraData.renderer.cameraColorTarget;
            
            RenderingUtils.Blit(cmd, source, colorBuffer.GetFrontBuffer().id, m_BlitMaterial, 0, useDrawProceduleBlit,
                RenderBufferLoadAction.DontCare,
                RenderBufferStoreAction.Store,
                RenderBufferLoadAction.DontCare,
                RenderBufferStoreAction.DontCare);
            
            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.LinearToSRGBConversion, false);
            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SRGBToLinearConversion,false);
            
            if (needChangeSize)
            {
                colorBuffer.ReSizeBackBufferAndSave(cmd, m_Width, m_Height);
                renderer.ResizeDepth(cmd, ref RenderTargetBufferSystem.m_Desc, m_Width, m_Height);
            }
            PostProcessUtils.SetSourceSize(cmd,RenderTargetBufferSystem.m_Desc);
            
            renderer.SwapColorBuffer(cmd);
            
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
    }
}